package com.ddxcloud.movie.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.Optional;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@EnableAsync
@AutoConfiguration
public class ThreadPoolConfig {

	/**
	 * 获取当前机器的核数, 不一定准确 请根据实际场景 CPU密集 || IO 密集
	 */
	public static final int cpuNum = Runtime.getRuntime().availableProcessors();

	@Value("${thread.pool.corePoolSize:}")
	private Optional<Integer> corePoolSize;

	@Value("${thread.pool.maxPoolSize:}")
	private Optional<Integer> maxPoolSize;

	@Value("${thread.pool.queueCapacity:}")
	private Optional<Integer> queueCapacity;

	@Value("${thread.pool.awaitTerminationSeconds:}")
	private Optional<Integer> awaitTerminationSeconds;

	@Bean("default")
	public Executor taskExecutor() {
		ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
		// 设置线程池核心容量
		taskExecutor.setCorePoolSize(corePoolSize.orElse(cpuNum));
		// 设置线程池最大容量 （CPU * 2）
		taskExecutor.setMaxPoolSize(maxPoolSize.orElse(cpuNum * 2));
		// 设置任务队列长度
		taskExecutor.setQueueCapacity(queueCapacity.orElse(500));
		// 设置线程超时时间
		taskExecutor.setKeepAliveSeconds(60);
		// 设置线程名称前缀
		taskExecutor.setThreadNamePrefix("DEFAULT-Thread-");
		// 拒绝处理策略：CallerRunsPolicy() 交由调用方线程运行
		taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
		// 设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean，这样这些异步任务的销毁就会先于Redis线程池的销毁
		taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
		// 设置线程池中任务的等待时间，如果超过这个时候还没有销毁就强制销毁，以确保应用最后能够被关闭，而不是阻塞状态
		taskExecutor.setAwaitTerminationSeconds(awaitTerminationSeconds.orElse(60));
		// 加载
		taskExecutor.initialize();
		return taskExecutor;
	}
}
